package com.ratingbay.console.restful;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
import java.io.*;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.ratingbay.console.common.RatingBayConst;
import com.ratingbay.console.dataface.*;
import com.ratingbay.console.dataimpl.TwitterUserImplWithTwitterProfile;
import com.ratingbay.console.restful.builder.*;
import com.ratingbay.console.service.ITwitterUserService;
import com.ratingbay.console.model.*;

@Controller
@RequestMapping("/rest/game")
public class GameRestful extends BaseRestful{
	
	@RequestMapping(value="/tweetHistory/{idGame}", method=RequestMethod.GET)
	public @ResponseBody
	Map getTweetHistory(@PathVariable Long idGame){
		Date beforeDate = new Date( System.currentTimeMillis() - 3*2592000000L );
        Date curDate = new Date( System.currentTimeMillis() );
		List<RbGameTweetTrend> tweetHistory = getGameApi().getTweetHistory(idGame,beforeDate,curDate);
		return decoratTweetHistory(tweetHistory);
	}
	
	@RequestMapping(value="/scoreHistory/{idGame}", method=RequestMethod.GET)
	public @ResponseBody
	Map getScoreHistory(@PathVariable Long idGame){
		Date beforeDate = new Date( System.currentTimeMillis() - 2592000000L );
        Date curDate = new Date( System.currentTimeMillis() );
		List<SentimentScoreHistory> scoreHistory = getGameApi().getScoreHistory(idGame,beforeDate,curDate);
		return decoratscoreHistory(scoreHistory);
	}
	
	@RequestMapping(value="/searchGamesAndUsers/{content}", method=RequestMethod.GET)
	public @ResponseBody
	Map getSearchGamesAndUsers(@PathVariable String content){
		List<Game> searchGames = getGameApi().getGameByTitleLike(content, 0, 10);
		return decoratGamesAndUsers(searchGames);
	}

    @RequestMapping(value="/topRatedGames/{page}", method=RequestMethod.GET)
    public @ResponseBody 
    Map getTopRatedGames(@PathVariable int page){
        Date beforeDate = new Date( System.currentTimeMillis() - 3*5184000000L );
        Date curDate = new Date( System.currentTimeMillis() );
        Date afterDate = new Date( System.currentTimeMillis() + 3*5184000000L );

        List<IGameSummary> topRatedGames = getGameApi().getTopRatedGames(beforeDate, afterDate, page, 10);
        return decoratIGameSummary(topRatedGames, page);
    }

    @RequestMapping(value="/topTweetedGames/{page}", method=RequestMethod.GET)
    public @ResponseBody 
    Map getTopTweetedGames(@PathVariable int page){
        Date beforeDate = new Date( System.currentTimeMillis() - 3*5184000000L );
        Date curDate = new Date( System.currentTimeMillis() );
        Date afterDate = new Date( System.currentTimeMillis() + 3*5184000000L );

        List<IGameSummary> topTweetedGames = getGameApi().getTopTweetedGamesRestul(beforeDate, afterDate, page, 10);
        return decoratIGameSummary(topTweetedGames, page);
    }

    @RequestMapping(value="/comingSoonGames/{page}", method=RequestMethod.GET)
    public @ResponseBody 
    Map getComingSoonGames(@PathVariable int page){
        Date beforeDate = new Date( System.currentTimeMillis() - 3*5184000000L );
        Date curDate = new Date( System.currentTimeMillis() );
        Date afterDate = new Date( System.currentTimeMillis() + 3*5184000000L );

        List<IGameSummary> comingSoonGames = new ArrayList<IGameSummary>();
        List<IGameSummary> topTweetedGames = getGameApi().getTopTweetedGames(beforeDate, afterDate, page, 10);;
        if(null != topTweetedGames){
            for(int i=0; i < topTweetedGames.size(); i++){
                if(topTweetedGames.get(i).getReleaseDate().after(curDate)){
                    comingSoonGames.add(topTweetedGames.get(i));
                }
            }
        }
        return decoratIGameSummary(comingSoonGames, page);
    }

    @RequestMapping(value="/newReleasedGames/{page}", method=RequestMethod.GET)
    public @ResponseBody 
    Map getNewReleasedGames(@PathVariable int page){
        Date beforeDate = new Date( System.currentTimeMillis() - 3*5184000000L );
        Date curDate = new Date( System.currentTimeMillis() );
        Date afterDate = new Date( System.currentTimeMillis() + 3*5184000000L );

        List<IGameSummary> newReleasedGames = new ArrayList<IGameSummary>();
        List<IGameSummary> topTweetedGames = getGameApi().getTopTweetedGames(beforeDate, afterDate, page, 10);;
        if(null != topTweetedGames){
            for(int i=0; i < topTweetedGames.size(); i++){
                if(topTweetedGames.get(i).getReleaseDate().before(curDate)){
                    newReleasedGames.add(topTweetedGames.get(i));
                }
            }
        }
        return decoratIGameSummary(newReleasedGames, page);
    }

    @RequestMapping(value="/recommendedGames/{idGame}/{page}", method=RequestMethod.GET)
    public @ResponseBody 
    Map getNewReleasedGames(@PathVariable Long idGame, @PathVariable int page){

        Page<IGameSummary> recommendedGames = getGameApi().getRecommendedGamesByGame(
            idGame, page, 5);

        return decoratIGameSummary(recommendedGames, page);
    }

    @RequestMapping(value="/searchGames/{title}/{page}", method=RequestMethod.GET)
    public @ResponseBody 
    Map getSearchGames(@PathVariable String title, @PathVariable int page){
        String gOrderStr = "order by gs.tweet_count desc";
        Page<IGameSummary> searchGames = getGameApi().getGamesByTitle(title, page, 5);
        return decoratIGameSummary(searchGames, page);
    }
    @RequestMapping(value="/searchOrderedGames/{title}/{f}/{d}/{page}", method=RequestMethod.GET)
    public @ResponseBody 
    Map getSearchOrderedGames(@PathVariable String title, @PathVariable String f, @PathVariable String d, @PathVariable int page){
        Page<IGameSummary> searchGames = getGameApi().getGamesByTitle(title, f, d, page, 5);
        return decoratIGameSummary(searchGames, page);
    }

    @RequestMapping(value="/getGameWaters/{title}/{page}", method=RequestMethod.GET) 
    public ModelAndView getGameWaters(HttpServletRequest req,@PathVariable String title, @PathVariable int page){
        Page<IGameSummary> searchGames = getGameApi().getGamesByTitle(title, page, 5);
        List<Long> tUserIds = getTUserApi().getTwitterFriendsIds();
        Set<Long> ids=new HashSet<Long>(tUserIds);
        List<Long> userIds=new ArrayList<Long>(ids);
        if(userIds.size() > 1){
            Iterator<IGameSummary> it = searchGames.iterator();
            IGameSummary gameSummary;
            Page<Tweet> tweetsOfPage;
            Page<Tweet> tweetsOfPageForUserId;
            while(it.hasNext()){
                gameSummary = it.next();
                tweetsOfPage = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                		userIds, 0, 5);
                tweetsOfPageForUserId = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                        tUserIds, 0, 100);
                gameSummary.setFriendsTweets(tweetsOfPage.getContent());
                //查询用户
                List<ITwitterUser> ll=new ArrayList<ITwitterUser>();
            	Set<Long> uids=new HashSet<Long>();
                for(Tweet t:tweetsOfPageForUserId.getContent()){
                	if(uids.size() < 5){
                	uids.add(t.getUserId());
                	}
                }
                for(Long id:uids){
                	ITwitterUser u=getTUserApi().getITwitterUser(id);
                	ll.add(u);
                }
                gameSummary.setTwitterUsers(ll);
            }  
        }

        ModelMap model = new ModelMap();
        model.addAttribute( "gameList", searchGames.getContent() );
        model.addAttribute( "IRestfulViewContentBuilder", 
            new WaterBuilderImpl() );

        Map<String, Object> retMap = new HashMap();
        retMap.put( "hasNext", searchGames.hasNextPage());
        model.addAttribute( "retMap", retMap );

        return new ModelAndView("restful/gameWater", model);
    }
    @RequestMapping(value="/getOrderedGameWaters/{title}/{f}/{d}/{page}", method=RequestMethod.GET) 
    public ModelAndView getOrderedGameWaters(@PathVariable String title, @PathVariable String f, @PathVariable String d, @PathVariable int page){
        Page<IGameSummary> searchGames = getGameApi().getGamesByTitle(title, f, d, page, 5);
        List<Long> tUserIds = getTUserApi().getTwitterFriendsIds();

        if(tUserIds.size() > 1){
            Iterator<IGameSummary> it = searchGames.iterator();
            IGameSummary gameSummary;
            Page<Tweet> tweetsOfPage;
            Page<Tweet> tweetsOfPageForUserId;
            while(it.hasNext()){
                gameSummary = it.next();
                tweetsOfPageForUserId = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                    tUserIds, 0, 100);
                tweetsOfPage = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                        tUserIds, 0, 5);
                gameSummary.setFriendsTweets(tweetsOfPage.getContent());
              //查询用户
                List<ITwitterUser> ll=new ArrayList<ITwitterUser>();
            	Set<Long> uids=new HashSet<Long>();
                for(Tweet t:tweetsOfPageForUserId.getContent()){
                	if(uids.size() < 5){
                	uids.add(t.getUserId());
                	}
                }
                for(Long id:uids){
                	ITwitterUser u=getTUserApi().getITwitterUser(id);
                	ll.add(u);
                }
                gameSummary.setTwitterUsers(ll);
            }  
        }

        ModelMap model = new ModelMap();
        model.addAttribute( "gameList", searchGames.getContent() );
        model.addAttribute( "IRestfulViewContentBuilder", 
            new WaterBuilderImpl() );

        Map<String, Object> retMap = new HashMap();
        retMap.put( "hasNext", searchGames.hasNextPage());
        model.addAttribute( "retMap", retMap );

        return new ModelAndView("restful/gameWater", model);
    }
    
    //search all game
    @RequestMapping(value="/getGameWaters//{page}", method=RequestMethod.GET) 
    public ModelAndView getAllGameWaters(HttpServletRequest req,@PathVariable int page){
    	String title="";
        Page<IGameSummary> searchGames = getGameApi().getGamesByTitle(title, page, 5);
        List<Long> tUserIds = getTUserApi().getTwitterFriendsIds();
        Set<Long> ids=new HashSet<Long>(tUserIds);
        List<Long> userIds=new ArrayList<Long>(ids);
        if(userIds.size() > 1){
            Iterator<IGameSummary> it = searchGames.iterator();
            IGameSummary gameSummary;
            Page<Tweet> tweetsOfPage;
            Page<Tweet> tweetsOfPageForUserId;
            while(it.hasNext()){
                gameSummary = it.next();
                tweetsOfPage = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                		userIds, 0, 5);
                tweetsOfPageForUserId = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                        tUserIds, 0, 100);
                gameSummary.setFriendsTweets(tweetsOfPage.getContent());
                //查询用户
                List<ITwitterUser> ll=new ArrayList<ITwitterUser>();
            	Set<Long> uids=new HashSet<Long>();
                for(Tweet t:tweetsOfPageForUserId.getContent()){
                	if(uids.size() < 5){
                	uids.add(t.getUserId());
                	}
                }
                for(Long id:uids){
                	ITwitterUser u=getTUserApi().getITwitterUser(id);
                	ll.add(u);
                }
                gameSummary.setTwitterUsers(ll);
            }  
        }

        ModelMap model = new ModelMap();
        model.addAttribute( "gameList", searchGames.getContent() );
        model.addAttribute( "IRestfulViewContentBuilder", 
            new WaterBuilderImpl() );

        Map<String, Object> retMap = new HashMap();
        retMap.put( "hasNext", searchGames.hasNextPage());
        model.addAttribute( "retMap", retMap );

        return new ModelAndView("restful/gameWater", model);
    }
    @RequestMapping(value="/getOrderedGameWaters//{f}/{d}/{page}", method=RequestMethod.GET) 
    public ModelAndView getAllOrderedGameWaters(@PathVariable String f, @PathVariable String d, @PathVariable int page){
    	String title ="";
        Page<IGameSummary> searchGames = getGameApi().getGamesByTitle(title, f, d, page, 5);
        List<Long> tUserIds = getTUserApi().getTwitterFriendsIds();

        if(tUserIds.size() > 1){
            Iterator<IGameSummary> it = searchGames.iterator();
            IGameSummary gameSummary;
            Page<Tweet> tweetsOfPage;
            Page<Tweet> tweetsOfPageForUserId;
            while(it.hasNext()){
                gameSummary = it.next();
                tweetsOfPageForUserId = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                    tUserIds, 0, 100);
                tweetsOfPage = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                        tUserIds, 0, 5);
                gameSummary.setFriendsTweets(tweetsOfPage.getContent());
              //查询用户
                List<ITwitterUser> ll=new ArrayList<ITwitterUser>();
            	Set<Long> uids=new HashSet<Long>();
                for(Tweet t:tweetsOfPageForUserId.getContent()){
                	if(uids.size() < 5){
                	uids.add(t.getUserId());
                	}
                }
                for(Long id:uids){
                	ITwitterUser u=getTUserApi().getITwitterUser(id);
                	ll.add(u);
                }
                gameSummary.setTwitterUsers(ll);
            }  
        }

        ModelMap model = new ModelMap();
        model.addAttribute( "gameList", searchGames.getContent() );
        model.addAttribute( "IRestfulViewContentBuilder", 
            new WaterBuilderImpl() );

        Map<String, Object> retMap = new HashMap();
        retMap.put( "hasNext", searchGames.hasNextPage());
        model.addAttribute( "retMap", retMap );

        return new ModelAndView("restful/gameWater", model);
    }

    //search released and coming game
    @RequestMapping(value="/allGames/{ag}/{page}", method=RequestMethod.GET) 
    public ModelAndView getReleasedGameWaters(HttpServletRequest req,@PathVariable int page,@PathVariable String ag){
    	Date curDate = new Date( System.currentTimeMillis() );
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
		Date now = formatter.parse(formatter.format(curDate), pos);
		Page<IGameSummary> searchGames;
		String re= "released";
		if(ag.equals(re)){
			searchGames = getGameApi().getReleasedGames(now, page, 5);
		}else{
			searchGames = getGameApi().getComingGames(now, page, 5);
		}
        List<Long> tUserIds = getTUserApi().getTwitterFriendsIds();
        Set<Long> ids=new HashSet<Long>(tUserIds);
        List<Long> userIds=new ArrayList<Long>(ids);
        if(userIds.size() > 1){
            Iterator<IGameSummary> it = searchGames.iterator();
            IGameSummary gameSummary;
            Page<Tweet> tweetsOfPage;
            Page<Tweet> tweetsOfPageForUserId;
            while(it.hasNext()){
                gameSummary = it.next();
                tweetsOfPage = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                		userIds, 0, 5);
                tweetsOfPageForUserId = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                        tUserIds, 0, 100);
                gameSummary.setFriendsTweets(tweetsOfPage.getContent());
                //查询用户
                List<ITwitterUser> ll=new ArrayList<ITwitterUser>();
            	Set<Long> uids=new HashSet<Long>();
                for(Tweet t:tweetsOfPageForUserId.getContent()){
                	if(uids.size() < 5){
                	uids.add(t.getUserId());
                	}
                }
                for(Long id:uids){
                	ITwitterUser u=getTUserApi().getITwitterUser(id);
                	ll.add(u);
                }
                gameSummary.setTwitterUsers(ll);
            }  
        }

        ModelMap model = new ModelMap();
        model.addAttribute( "gameList", searchGames.getContent() );
        model.addAttribute( "IRestfulViewContentBuilder", 
            new WaterBuilderImpl() );

        Map<String, Object> retMap = new HashMap();
        retMap.put( "hasNext", searchGames.hasNextPage());
        model.addAttribute( "retMap", retMap );

        return new ModelAndView("restful/gameWater", model);
    }
    @RequestMapping(value="/allGames/{ag}/{f}/{d}/{page}", method=RequestMethod.GET) 
    public ModelAndView getReleasedOrderedGameWaters(@PathVariable String ag,@PathVariable String f, @PathVariable String d, @PathVariable int page){
    	Date curDate = new Date( System.currentTimeMillis() );
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
		Date now = formatter.parse(formatter.format(curDate), pos);
    	Page<IGameSummary> searchGames;
    	String re= "released";
		if(ag.equals(re)){
			searchGames = getGameApi().getReleasedGames(now, f, d, page, 5);
		}else{
			searchGames = getGameApi().getComingGames(now, f, d, page, 5);
		}
        List<Long> tUserIds = getTUserApi().getTwitterFriendsIds();

        if(tUserIds.size() > 1){
            Iterator<IGameSummary> it = searchGames.iterator();
            IGameSummary gameSummary;
            Page<Tweet> tweetsOfPage;
            Page<Tweet> tweetsOfPageForUserId;
            while(it.hasNext()){
                gameSummary = it.next();
                tweetsOfPageForUserId = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                    tUserIds, 0, 100);
                tweetsOfPage = getTweetApi().getUsersTweetsByGame(gameSummary.getId(),
                        tUserIds, 0, 5);
                gameSummary.setFriendsTweets(tweetsOfPage.getContent());
              //查询用户
                List<ITwitterUser> ll=new ArrayList<ITwitterUser>();
            	Set<Long> uids=new HashSet<Long>();
                for(Tweet t:tweetsOfPageForUserId.getContent()){
                	if(uids.size() < 5){
                	uids.add(t.getUserId());
                	}
                }
                for(Long id:uids){
                	ITwitterUser u=getTUserApi().getITwitterUser(id);
                	ll.add(u);
                }
                gameSummary.setTwitterUsers(ll);
            }  
        }

        ModelMap model = new ModelMap();
        model.addAttribute( "gameList", searchGames.getContent() );
        model.addAttribute( "IRestfulViewContentBuilder", 
            new WaterBuilderImpl() );

        Map<String, Object> retMap = new HashMap();
        retMap.put( "hasNext", searchGames.hasNextPage());
        model.addAttribute( "retMap", retMap );

        return new ModelAndView("restful/gameWater", model);
    }
    
    //used in class inner
    protected Map decoratIGameSummary(List<IGameSummary> gameSummaryList, int page){
        Map dataJson = new HashMap<String, Object>();
        List result = getGameSummaryList(gameSummaryList.iterator());
        dataJson.put("result", result);
        dataJson.put("status", 1);
        dataJson.put("page", page);
        boolean hasNext = (10 == gameSummaryList.size());
        dataJson.put("hasNext", hasNext);
        return dataJson;
    }
    protected Map decoratTweetHistory(List<RbGameTweetTrend> tweetHistory){
        Map dataJson = new HashMap<String, Object>();
        List result = new ArrayList<Map>();
        Map resultOne;
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Iterator<RbGameTweetTrend> it = tweetHistory.iterator();
        RbGameTweetTrend th;
        while(it.hasNext()){
        	th = it.next();
        	resultOne = new HashMap<String, Object>();
        	resultOne.put("tweetCount", th.getTweetCount());
        	String res = format.format(th.getCreateDate());
        	resultOne.put("create_date", res);
        	result.add(resultOne);
        }
        
        dataJson.put("result", result);
        dataJson.put("status", 1);
        return dataJson;
    }
    protected Map decoratscoreHistory(List<SentimentScoreHistory> scoreHistory){
        Map dataJson = new HashMap<String, Object>();
        List result = new ArrayList<Map>();
        Map resultOne;
        Iterator<SentimentScoreHistory> it = scoreHistory.iterator();
        SentimentScoreHistory score;
        while(it.hasNext()){
        	score = it.next();
        	resultOne = new HashMap<String, Object>();
        	resultOne.put("score", score.getScore());
        	DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        	String res = format.format(score.getInsertTime());
        	resultOne.put("insert_time", res);
        	result.add(resultOne);
        }
        
        dataJson.put("result", result);
        dataJson.put("status", 1);
        return dataJson;
    }

    protected Map decoratIGameSummary(Page<IGameSummary> gameSummaryOfPage, int page){
        Map dataJson = new HashMap<String, Object>();
        List result = getGameSummaryList(gameSummaryOfPage.iterator());
        dataJson.put("result", result);
        dataJson.put("status", 1);
        dataJson.put("page", page);
        dataJson.put("hasNext", gameSummaryOfPage.hasNextPage());
        return dataJson;
    }

    protected List getGameSummaryList(Iterator<IGameSummary> it){
        List result = new ArrayList<Map>();
        IGameSummary gameSummary; 
        Map resultOne;
        while(it.hasNext()){
            gameSummary = it.next();

            resultOne = new HashMap<String, Object>();
            resultOne.put("score", gameSummary.getSentimentScore());
            resultOne.put("name", gameSummary.getTitle());
            resultOne.put("tweetsCount", gameSummary.getTweetCount());
            resultOne.put("dvdImagePath", gameSummary.getDvdImagePath());
            resultOne.put("releaseDate", gameSummary.getReleaseDate());
            resultOne.put("description", gameSummary.getDescription());
            resultOne.put("id", gameSummary.getId());

            result.add(resultOne);
        }
        return result;
    }
    
    //protected Map decoratGamesAndUsers(List<Game>searchGames,List<TwitterUser>searchUsers){
    protected Map decoratGamesAndUsers(List<Game>searchGames){
    	Map dataJson = new HashMap<String, Object>();
    	
        List game = new ArrayList<Map>();
        Map gameOne;
        Iterator<Game> it = searchGames.iterator();
        while(it.hasNext()){
        	Game g;
        	g=it.next();
        	gameOne = new HashMap<String, Object>();
        	gameOne.put("gameName", g.getTitle());
        	gameOne.put("gameId", g.getId());
        	game.add(gameOne);
        }
        
        dataJson.put("game",game);
        return dataJson;
    }
}
